import { message, Slider } from 'antd';
import React, { memo, useCallback, useEffect, useRef, useState } from 'react';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { getSizeImage, formatDate, getPlaySong } from '@/tools/data_format';
import { changeCurrentSong, changeLyricingAction, changeOrderAction, getSongDetailAction } from '../store/actionCreators';
import { Control, Operator, PlaybarWrapper, PlayInfo } from './style';
import { NavLink } from 'react-router-dom';


const AppPlayerBar = memo(() => {
    // state and props 
    const [currentTime, setCurrentTime] = useState(0)//实时更新的时间
    const [progress, setProgress] = useState(0)//当前播放的时间
    const [isChangeimg, setIsChangeimg] = useState(true)//是否存在手拉动滑块
    const [isPlaying, setIsplaying] = useState(false)//是否正在播放
    // Hooks 
    const dispatch = useDispatch()
    const { currentSong, order, playList, lyricList, lyricing } = useSelector(state => {
        return {
            currentSong: state.getIn(['player', 'currentSong']),
            order: state.getIn(['player', 'order']),
            playList: state.getIn(['player', 'playList']),
            lyricList: state.getIn(['player', 'lyricList']),
            lyricing: state.getIn(['player', 'lyricing'])
        }
    }, shallowEqual)
    useEffect(() => {
        dispatch(getSongDetailAction(1827600686))
    }, [dispatch])
    useEffect(() => {
        //播放地址
        audioRef.current.src = getPlaySong(currentSong.id || 11564);
        //页面第一次渲染的时候谷歌浏览器不让默认播放 不然会报错
        //这里捕获他报错时把按钮暂停就行了
        audioRef.current.play().then(res => {
            setIsplaying(true)
        }).catch(err => {
            setIsplaying(false)
        });
    }, [currentSong])//这里依赖的是载入时的对象 当对象发生改变就等于换了一个歌
    const audioRef = useRef()
    //处理默认值
    //防止一开始页面渲染时拿到的是undefined
    const picUrl = (currentSong.al && currentSong.al.picUrl) || "";
    const songName = currentSong.name || "未知歌名";
    const singerName = (currentSong.ar && currentSong.ar[0].name) || "未知歌手";
    const currentSongTime = currentSong.dt || 0
    const songTime = formatDate(currentSongTime, "mm:ss")
    const showCurrentTime = formatDate(currentTime, "mm:ss")
    // function
    const palyMusic = (e) => {
        //这里更改状态是异步的 他会延迟更新一吃所以我们在判断的时候故意让它为false时播放 为true时暂停
        setIsplaying(!isPlaying)
        if (!isPlaying) {
            //播放
            audioRef.current.play();
        } else {
            //暂停
            audioRef.current.pause()
        }
    }
    //初始化歌词
    let lyricings = lyricList[0] && lyricList[0].content
    const timeUpdate = (e) => {
        //把进度条分成一百份歌曲时间每更新一下进度条就相应的前进对应的比例 antd的进度条默认比例是0-100这里我设置到了0-1000可以让进度条走的更平滑
        //比例: 当前播放时间/歌曲总时间*100
        if (isChangeimg) {
            // e.target.currentTime是获取音频实时更新的时间
            setCurrentTime(e.target.currentTime * 1000)
            //判断滑块值是否正在手动改变 如果是的话就不让后面的时间进行持续更新了
            //让更新的值有手动改变的值决定
            setProgress(currentTime / currentSongTime * 1000)
        }
        //更新歌词
        const lyricIndex = lyricList.findIndex((item, index) => {
            return item.time > e.target.currentTime*1000
        })
        lyricings =  lyricList[lyricIndex-1] &&  lyricList[lyricIndex-1].content
        //页面歌词展示
        if(lyricings !== lyricing){
           dispatch(changeLyricingAction(lyricings))
           message.open({
            key:"lyricing",
            content:lyricings,
            duration:0,
            className:'lyricing'
        })
        }
    }
    //当滑块值发生改变时(手动拉动改变)
    const sliderChange = useCallback((value) => {
        if (isNaN(value)) {
            return;
        }
        const ChangeAfterTime = value / 1000 * currentSongTime
        //这里需要重新定义一下实时更新的时间当你拉动滑块时后面的时间也跟着变化
        setCurrentTime(ChangeAfterTime)
        setIsChangeimg(false)
        setProgress(value)
    }, [currentSongTime])
    //当鼠标拉动滑块并松开左键时触发
    const sliderAfterChange = useCallback((value) => {
        //这里为什么多此一举呢?
        //因为我想让你知道这两个1000意义是不一样的
        //第一个1000是设置进度条最大值的1000第二个1000是因为算出来是秒需要转换成毫秒(这个属性需要的是毫秒)
        const ChangeAfterTime = value /1000 * currentSongTime / 1000
        //这里需要重新定义一下实时更新的时间 不然他会先回弹一下之前的进度再跳到现在的进度 *1000是因为上面是毫秒值
        setCurrentTime(ChangeAfterTime * 1000)
        //从松开左键时的值开始播放 currentTime这个可以更改音频从哪里开始播放
        audioRef.current.currentTime = ChangeAfterTime
        setIsChangeimg(true)
        //拉动滑块并松开时开启播放
        audioRef.current.play();
        setIsplaying(true)
    }, [currentSongTime])
    //播放顺序
    const changeOrder = () => {
        let currentOrder = order + 1
        if (currentOrder > 2) {
            currentOrder = 0
        }
        dispatch(changeOrderAction(currentOrder))
    }
    //上一首歌曲(-1) or 下一首歌曲(1)
    const chageMusic = (tag) => {
        if (playList.length === 1) {
            //直接让它重新开始播放就行了
            audioRef.current.currentTime = 0;
            audioRef.current.play();
            setIsplaying(true)
        } else {
            dispatch(changeCurrentSong(tag))
        }
    }
    //当音乐播放完成后
    const handleEnded = () => {
        if (order === 2) {
            //单曲循环  这里不能传入0 因为你值没变当他去更新状态时发现什么都没变就不会帮你更新状态
            // dispatch(changeCurrentSong(0))

            //直接让它重新开始播放就行了
            audioRef.current.currentTime = 0;
            audioRef.current.play();
        } else {
            if (playList.length === 1) {
                console.log(123);
                //直接让它重新开始播放就行了
                audioRef.current.currentTime = 0;
                audioRef.current.play();
            } else {
                //切换下一首
                dispatch(changeCurrentSong(1))
            }
        }

    }
    return (
        <PlaybarWrapper className="sprite_player">
            <div className="content wrap-v2">
                <Control isPlaying={isPlaying}>
                    <button className="sprite_player prev" onClick={e => chageMusic(-1)}></button>
                    <button className="sprite_player play" onClick={palyMusic}></button>
                    <button className="sprite_player next" onClick={e => chageMusic(1)}></button>
                </Control>
                <PlayInfo>
                    <div className="image">
                        <NavLink to={{pathname:`/player/?id=${currentSong.id}`,state:{songData:currentSong}}}>
                            <img src={getSizeImage(picUrl, 35)} alt="" />
                        </NavLink>
                    </div>
                    <div className="info">
                        <div className="song">
                            <a href="/stand-by" className="song-name">{songName}</a>
                            <a href="/stand-by" className="singer-name">{singerName}</a>

                        </div>
                        <div className="progress">
                            <Slider
                                value={progress} max="1000"
                                onChange={sliderChange}
                                onAfterChange={sliderAfterChange} />
                            <div className="time">
                                <span className="now-time">{showCurrentTime}</span>
                                <span className="divider"></span>
                                <span className="duration">{songTime}</span>
                            </div>
                        </div>
                    </div>
                </PlayInfo>
                <Operator order={order}>
                    <div className="left">
                        <button className="sprite_player btn favor"></button>
                        <button className="sprite_player btn share"></button>
                    </div>
                    <div className="right sprite_player">
                        <button className="sprite_player btn volume"></button>
                        <button className="sprite_player btn loop" onClick={e => changeOrder()}></button>
                        <button className="sprite_player btn playlist"></button>
                    </div>
                </Operator>
            </div>
            {/* 音频播放 onTimeUpdate属性是播放时间的更新 里面可以传递一个函数用于回调接收 onEnded是音乐播放完成后接收一个回调函数 */}
            <audio ref={audioRef} onTimeUpdate={timeUpdate} onEnded={handleEnded} />
        </PlaybarWrapper>
    );
});

export default AppPlayerBar;